package redisx

import (
	"time"

	"github.com/redis/go-redis/v9"
)

// Set ...
func Set(key, val string, expiration time.Duration) error {
	return Client.Set(ctx, key, val, expiration).Err()
}

// Get ...
func Get(key string) (string, error) {
	ret, err := Client.Get(ctx, key).Result()
	if err != nil && err != redis.Nil {
		return "", err
	}
	return ret, nil
}

// Del 删除key
func Del(keys ...string) error {
	return Client.Del(ctx, keys...).Err()
}

// Incr 指定key的值+1
func Incr(key string) error {
	return Client.Incr(ctx, key).Err()
}

// Decr 指定key的值-1
func Decr(key string) error {
	return Client.Decr(ctx, key).Err()
}

// 批量设置，没有过期时间
func MSet(values ...any) error {
	return Client.MSet(ctx, values...).Err()
}

// 批量设置取数据
// 示例：values, err := MGet(key1, key2)
// for i, _ := range values {
// fmt.Println(values[i])
// }
func MGet(keys ...string) ([]any, error) {
	return Client.MGet(ctx, keys...).Result()
}

// 执行命令
// 返回结果
// s, err := cmd.Text()
// flag, err := cmd.Bool()
// num, err := cmd.Int()
// num, err := cmd.Int64()
// num, err := cmd.Uint64()
// num, err := cmd.Float32()
// num, err := cmd.Float64()
// ss, err := cmd.StringSlice()
// ns, err := cmd.Int64Slice()
// ns, err := cmd.Uint64Slice()
// fs, err := cmd.Float32Slice()
// fs, err := cmd.Float64Slice()
// bs, err := cmd.BoolSlice()
func Do(args ...any) *redis.Cmd {
	return Client.Do(ctx, args)
}

// 清空缓存
func FlushDB() error {
	return Client.FlushDB(ctx).Err()
}

// 发布
// 示例Publish("mychannel1", "payload").Err()
func Publish(channel string, msg string) error {
	return Client.Publish(ctx, channel, msg).Err()
}

// 订阅
func Subscribe(channel string, subscribe func(msg *redis.Message, err error)) {
	pubsub := Client.Subscribe(ctx, channel)
	defer pubsub.Close()

	for {
		msg, err := pubsub.ReceiveMessage(ctx)
		subscribe(msg, err)
	}
}

// 列表的头部（左边）,尾部（右边）
// 列表左边插入
func LPust(channel string, values ...any) error {
	return Client.LPush(ctx, channel, values...).Err()
}

// 列表从左边开始取出start至stop位置的数据
func LRange(key string, start, stop int64) error {
	return Client.LRange(ctx, key, start, stop).Err()
}

// 列表左边取出
func LPop(key string) *redis.StringCmd {
	return Client.LPop(ctx, key)
}

// 列表右边插入
func RPust(channel string, values ...any) error {
	return Client.RPush(ctx, channel, values...).Err()
}

// 列表右边取出
func RPop(key string) error {
	return Client.RPop(ctx, key).Err()
}

// 列表哈希插入
func HSet(key string, values ...any) error {
	return Client.HSet(ctx, key, values...).Err()
}

// 列表哈希取出
func HGet(key, field string) *redis.StringCmd {
	return Client.HGet(ctx, key, field)
}

// 列表哈希批量插入
func HMSet(key string, values ...any) error {
	return Client.HMSet(ctx, key, values...).Err()
}

// 列表哈希批量取出
func HMGet(key string, fields ...string) []any {
	return Client.HMGet(ctx, key, fields...).Val()
}

// 列表无序集合插入
func SAdd(key string, members ...any) error {
	return Client.SAdd(ctx, key, members...).Err()
}

// 列表无序集合，返回所有元素
func SMembers(key string) []string {
	return Client.SMembers(ctx, key).Val()
}

// 列表无序集合，检查元素是否存在
func SIsMember(key string, member any) (bool, error) {
	if b, err := Client.SIsMember(ctx, key, member).Result(); err != nil {
		return false, err
	} else {
		return b, nil
	}
}
